<template>
  <div>
    <el-card class="box-card">
      <el-breadcrumb separator="/">
        <el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item>
        <el-breadcrumb-item>权限管理</el-breadcrumb-item>
        <el-breadcrumb-item>角色列表</el-breadcrumb-item>
      </el-breadcrumb>

      <el-table :data="tableData" border class="tabletop" style="width: 100%">
        <el-table-column type="expand">
          <template slot-scope="props">
            <el-row
              class="row-bg"
              justify="space-around"
              :class="['rowmenu', 'rowbottom', index == 0 ? 'rowtop' : '']"
              v-for="(item, index) in props.row.children"
              :key="index"
            >
              <!-- 一级菜单 -->
              <el-col :span="5">
                <el-tag>{{ item.authName }}</el-tag>
                <i class="el-icon-caret-right"></i>
              </el-col>
              <!-- 二级菜单 -->
              <el-col :span="19">
                <el-row
                  :class="['rowmenu', index2 == 0 ? '' : 'rowtop']"
                  v-for="(two, index2) in item.children"
                  :key="index2"
                >
                  <el-col :span="6">
                    <el-tag type="success">{{ two.authName }}</el-tag>
                    <i class="el-icon-caret-right"></i>
                  </el-col>
                  <!-- 三级菜单 -->
                  <el-col :span="18">
                    <el-row
                      v-for="(three, index3) in two.children"
                      :key="index3"
                    >
                      <el-tag
                        type="danger"
                        closable
                        @close="delrule(props.row, three.id)"
                        >{{ three.authName }}</el-tag
                      >
                    </el-row>
                  </el-col>
                </el-row>
              </el-col>
            </el-row>
          </template>
        </el-table-column>
        <el-table-column label="序号" type="index"></el-table-column>
        <el-table-column label="角色名称" prop="roleName"></el-table-column>
        <el-table-column label="角色描述" prop="roleDesc"></el-table-column>
        <el-table-column label="操作">
          <template slot="header">
            <el-button type="primary" size="mini" @click="isShow = true"
              >添加角色</el-button
            >
          </template>
          <el-table-column fixed="right" label="操作" width="320">
            <template slot-scope="{ row }">
              <el-button
                type="primary"
                size="mini"
                icon="el-icon-edit"
                @click="edit(row)"
                >编辑</el-button
              >
              <el-button
                type="danger"
                size="mini"
                icon="el-icon-delete"
                @click="del(row)"
                >删除</el-button
              >
              <el-button
                type="warning"
                size="mini"
                icon="el-icon-s-tools"
                @click="editpower(row)"
                >分配权限</el-button
              >
            </template>
          </el-table-column>
        </el-table-column>
      </el-table>
    </el-card>
    <!-- 添加弹框 -->
    <el-dialog title="添加角色" :visible.sync="isShow" width="30%">
      <el-form :model="addObj" label-width="100px" class="demo-ruleForm">
        <el-form-item label="角色名称" prop="roleName">
          <el-input v-model="addObj.roleName"></el-input>
        </el-form-item>
        <el-form-item label="角色描述" prop="roleDesc">
          <el-input v-model="addObj.roleDesc"></el-input>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="isShow = false">取 消</el-button>
        <el-button type="primary" @click="add">确 定</el-button>
      </span>
    </el-dialog>
    <el-dialog
      title="分配权限"
      @close="clearkeys()"
      :visible.sync="powerShow"
      :close-on-click-modal="false"
    >
      <el-tree
        :data="treeData"
        :props="defaultProps"
        :default-checked-keys="defaultDataKey"
        show-checkbox
        default-expand-all
        node-key="id"
        ref="tree"
        highlight-current
      ></el-tree>

      <div slot="footer" class="dialog-footer">
        <el-button @click="powerShow = false">取 消</el-button>
        <el-button type="primary" @click="setpower()">确 定</el-button>
      </div>
    </el-dialog>
    <!-- 编辑弹框 -->
    <el-dialog title="编辑角色" :visible.sync="dialogVisible" width="30%">
      <el-form :model="saveobj" label-width="100px" class="demo-ruleForm">
        <el-form-item label="ID">
          <el-input v-model="saveobj.id"></el-input>
        </el-form-item>
        <el-form-item label="角色名称">
          <el-input v-model="saveobj.roleName"></el-input>
        </el-form-item>
        <el-form-item label="角色描述">
          <el-input v-model="saveobj.roleDesc"></el-input>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="update">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
export default {
  name: "roles",
  data() {
    return {
      isShow: false,
      addObj: {
        roleName: "",
        roleDesc: "",
      },
      saveobj: {
        id: "",
        roleName: "",
        roleDesc: "",
      },
      dialogVisible: false,
      tableData: [], //表格数据源
      powerShow: false, //控制分配权限的弹窗
      treeData: [], //定义树形控件的数据源
      defaultProps: {
        label: "authName", //定义所需要展示文本的属性
        children: "children", //定义子节点对应的属性
      },
      defaultDataKey: [], //定义默认选中的菜单的数组
      ruleid: 0, //定义角色id
    };
  },
  methods: {
    async update() {
      let rst = await this.$http.put(`roles/${this.saveobj.id}`, this.saveobj);
      if (rst.meta.status == 200) {
        this.$message.success("修改成功！");
        this.dialogVisible = false;
        this.query();
      }
    },
    // 添加
    async add() {
      let rst = await this.$http.post("roles", this.addObj);
      if (rst.meta.status == 201) {
        this.$message.success(rst.meta.msg);
        this.clearForm();
        this.isShow = false;
        this.query();
      }
    },
    clearForm() {
      this.addObj.roleName = "";
      this.addObj.roleDesc = "";
    },
    // 编辑角色列表
    async edit(obj) {
      this.dialogVisible = true;
      this.saveobj.id = obj.id;
      this.saveobj.roleName = obj.roleName;
      this.saveobj.roleDesc = obj.roleDesc;
    },
    //定义del方法用于根据id删除一个角色信息
    del(obj) {
      this.$confirm("此操作将永久删除该文件, 是否继续?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(async () => {
          //当点击确认时需要执行的代码块
          let rst = await this.$http.delete(`roles\/${obj.id}`);
          if (rst.meta.status == 200) {
            //当后台响应状态码为200时则表示删除成功
            //调用查询方法
            this.query();
          } else {
            // 当删除失败时提示删除失败
            this.$message.error("删除失败");
          }
        })
        .catch(() => {
          this.$message.info("已取消删除");
        });
    },
    //当点击分配权限弹窗时触发的方法
    async setpower() {
      //获取被选中到的子节点的key数组
      let checkkey = this.$refs.tree.getCheckedKeys();
      //获取半选中状态的子节点的key数组
      let halfkey = this.$refs.tree.getHalfCheckedKeys();
      //将选中和半选中状态的节点key拼接到一个数组中,然后转为字符串
      let keys = [...checkkey, ...halfkey].join();
      console.log(keys);
      //发送分配权限的请求
      let rst = await this.$http.post(`roles/${this.ruleid}/rights`, {
        rids: keys,
      });
      if (rst.meta.status == 200) {
        this.$message.success("分配权限成功");
        //关闭弹窗
        this.powerShow = false;
        //调用查询方法
        this.query();
      } else {
        this.$message.error("分配权限失败");
      }
    },
    //重置默认选中key的方法
    clearkeys() {
      this.$refs.tree.setCheckedKeys([]);
    },
    //点击修改权限时触发的方法
    async editpower(row) {
      let rst = await this.$http.get("rights/tree");
      if (rst.meta.status == 200) {
        // 将档期那角色的id值赋值给ruleId
        this.ruleid = row.id;
        //打开弹窗
        this.powerShow = true;
        // 将结果赋值给treeData
        this.treeData = rst.data;
        // 调用递归函数
        this.getkeys(row, this.defaultDataKey);
        console.log(this.defaultDataKey);
      } else {
        this.$message.error("分配权限失败");
      }
    },
    //使用递归函数实现将所有的三级菜单的id存放在defaultDataKey中
    getkeys(node, array) {
      //当没有children属性时则表示该节点为三级节点
      if (!node.children) {
        array.push(node.id);
        return;
      }
      //如果该节点存在children属性则使用forEach遍历子节点,且调用自身函数
      node.children.forEach((item) => {
        this.getkeys(item, array);
      });
    },

    // 定义tag中点击关闭小图标时触发的事件,接收角色id和权限id
    delrule(row, rightId) {
      console.log(row);
      // 当点击时弹出确认删除提示框
      this.$confirm("此操作将永久删除该文件, 是否继续?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      }).then(
        async () => {
          //点击确认按钮触发的方法
          let rst = await this.$http.delete(
            `roles/${row.id}/rights/${rightId}`
          );
          if (rst.meta.status == 200) {
            console.log(rst);
            //  注意在删除之后服务器返回的响应数据中包含该角色目前所拥有的权限信息，属性为data。我们只需要将data的只赋值给row中的children属性即可
            row.children = rst.data;
          } else {
            this.$message.error("删除失败");
          }
        },
        () => {
          this.$message.info("取消删除了");
        }
      );
    },

    // 查询所有角色信息的方法
    async query() {
      let rst = await this.$http.get("roles");
      if (rst.meta.status == 200) {
        // 将结果赋值给数据源
        this.tableData = rst.data;
      } else {
        this.$message.error("获取结果失败");
      }
    },
  },
  mounted() {
    //调用查询所有角色信息的方法
    this.query();
  },
};
</script>

<style scoped>
.el-tag {
  margin: 7px;
}
.rowtop {
  border-top: 1px solid #f6f7f8;
}
.rowbottom {
  border-bottom: 1px solid #f6f7f8;
}
.rowmenu {
  display: flex;
  align-items: center; /*辅轴对齐*/
}
</style>
